#include "filter.h"
#include <iostream>
using namespace std;
QImage Filter::normalize(int *R,int *G,int *B){
    QImage qout=QImage(in_image->width(),in_image->height(),in_image->format());
    int rows=in_image->height();
    int cols=in_image->width();
    int i,j,max=0,min=255;
    for(i=0;i<cols;i++)
        for(j=0;j<rows;j++){
        if(R[i+j*cols]>max)
            max=R[i+j*cols];
        if(G[i+j*cols]>max)
            max=G[i+j*cols];
        if(B[i+j*cols]>max)
            max=B[i+j*cols];
        if(R[i+j*cols]<min)
            min=R[i+j*cols];
        if(G[i+j*cols]<min)
            min=G[i+j*cols];
        if(B[i+j*cols]<min)
            min=B[i+j*cols];
    }
    double m=255.0/(max-min);
    double c=-m*min;
    cout<<"m is"<<m<<"max is"<<max<<"min is"<<min<<endl;
    for(i=0;i<cols;i++)
        for(j=0;j<rows;j++){
        qout.setPixel(i,j,qRgb(m*R[i+j*cols]+c,m*G[i+j*cols]+c,m*B[i+j*cols]+c));
    }
    delete [] R;
    delete [] G;
    delete [] B;
    return qout;
    }

struct image Filter::convolve_img(QImage *in_image=NULL){
    int i,j,a,b,l,k;
    a=this->k_rows/2;
    b=this->k_cols/2;
    this->in_image=in_image;
    int cols=in_image->width();
    int rows=in_image->height();
    int *out_arrayR=new int[cols*rows];
    int *out_arrayG=new int[cols*rows];
    int *out_arrayB=new int[cols*rows];
    for(j=0;j<rows;j++)
    for(i=0;i<cols;i++)
    {
          out_arrayR[i+j*cols]=0;
          out_arrayG[i+j*cols]=0;
          out_arrayB[i+j*cols]=0;
          for(l=0;l<k_rows;l++)
          for(k=0;k<k_cols;k++)
          {
                  int jj=j+l-a;
                  int ii=i+k-b;
                  if(jj>=0 && ii>=0 && jj<in_image->height() && ii<in_image->width()){
                      int kernel_pos=this->k_rows-k-1+this->k_cols*(this->k_rows-l-1);
                      double ker_val=*(this->kernel+kernel_pos);
                      out_arrayR[i+j*cols]=out_arrayR[i+j*cols]+ker_val*qRed(in_image->pixel(ii,jj));
                      out_arrayG[i+j*cols]=out_arrayG[i+j*cols]+ker_val*qGreen(in_image->pixel(ii,jj));
                      out_arrayB[i+j*cols]=out_arrayB[i+j*cols]+ker_val*qBlue(in_image->pixel(ii,jj));
                  }
          }
    }
 // struct image img;
  img.R=out_arrayR;
  img.G=out_arrayG;
  img.B=out_arrayB;
  return img;
}
QImage Filter::convolve(QImage *in_image=NULL){
    int i,j,a,b,l,k;
    a=this->k_rows/2;
    b=this->k_cols/2;
    this->in_image=in_image;
    int cols=in_image->width();
    int rows=in_image->height();
    int *out_arrayR=new int[cols*rows];
    int *out_arrayG=new int[cols*rows];
    int *out_arrayB=new int[cols*rows];
    for(j=0;j<rows;j++)
    for(i=0;i<cols;i++)
    {
          out_arrayR[i+j*cols]=0;
          out_arrayG[i+j*cols]=0;
          out_arrayB[i+j*cols]=0;
          for(l=0;l<k_rows;l++)
          for(k=0;k<k_cols;k++)
          {
                  int jj=j+l-a;
                  int ii=i+k-b;
                  if(jj>=0 && ii>=0 && jj<in_image->height() && ii<in_image->width()){
                      int kernel_pos=this->k_rows-k-1+this->k_cols*(this->k_rows-l-1);
                      double ker_val=*(this->kernel+kernel_pos);
                      out_arrayR[i+j*cols]=out_arrayR[i+j*cols]+ker_val*qRed(in_image->pixel(ii,jj));
                      out_arrayG[i+j*cols]=out_arrayG[i+j*cols]+ker_val*qGreen(in_image->pixel(ii,jj));
                      out_arrayB[i+j*cols]=out_arrayB[i+j*cols]+ker_val*qBlue(in_image->pixel(ii,jj));                     
                  }
          }
    }
  return this->normalize(out_arrayR,out_arrayG,out_arrayB);    
}
QImage Filter::normalize(QImage *qin){
QImage qout=QImage(qin->width(),qin->height(),qin->format());
int rows=qin->height();
int cols=qin->width();
int i,j,max=0,min=255,R,G,B;
for(i=0;i<cols;i++)
    for(j=0;j<rows;j++){
    R=qRed(qin->pixel(i,j));
    G=qGreen(qin->pixel(i,j));
    B=qBlue(qin->pixel(i,j));
    if(R>max)
        max=R;
    if(G>max)
        max=G;
    if(B>max)
        max=B;
    if(R<min)
        min=R;
    if(G<min)
        min=G;
    if(B<min)
        min=B;
}
double m=255.0/(max-min);
double c=-m*min;
cout<<"m is"<<m<<"max is"<<max<<"min is"<<min<<endl;
for(i=0;i<cols;i++)
    for(j=0;j<rows;j++){
    R=qRed(qin->pixel(i,j));
    G=qGreen(qin->pixel(i,j));
    B=qBlue(qin->pixel(i,j));
    qout.setPixel(i,j,qRgb(m*R+c,m*G+c,m*B+c));
}
return qout;
}

Filter::~Filter(){


}
